package com.ytd.common.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.Process;
import android.os.SystemClock;
import android.util.Log;

import androidx.annotation.NonNull;

import com.jakewharton.processphoenix.ProcessPhoenix;

import java.io.PrintWriter;
import java.lang.reflect.Field;

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private static CrashHandler sInstance = new CrashHandler();
    private Thread.UncaughtExceptionHandler mDefaultCrashHandler;
    private Context mContext;

    public static CrashHandler getInstance() {
        return sInstance;
    }

    private Class mClass;

    public void setActivity(Class aClass) {
        mClass = aClass;
    }

    /**
     * 初始化
     *
     * @param context
     */
    public void init(Context context) {
        //得到系统的应用异常处理器
        mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
        //将当前应用异常处理器改为默认的
        Thread.setDefaultUncaughtExceptionHandler(this);
        mContext = context.getApplicationContext();
    }

    /**
     * 这个是最关键的函数，当系统中有未被捕获的异常，系统将会自动调用 uncaughtException 方法
     *
     * @param thread 为出现未捕获异常的线程
     * @param ex 为未捕获的异常 ，可以通过e 拿到异常信息
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        LogUtil.crashHandlerLog("------------------程序崩溃异常-----------------------------");
        LogUtil.crashHandlerLog(ex.getMessage() + "---" + Log.getStackTraceString(ex));

        LogUtil.crashHandlerLog("------------------程序自启动-----------------------------");
        ProcessPhoenix.triggerRebirth(mContext);
//        if (mClass != null) {
//            Intent intent = new Intent(mContext, mClass);
//            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
//            @SuppressLint("WrongConstant") PendingIntent pendingIntent = PendingIntent.getActivity(
//                mContext, 0,
//                intent, intent.getFlags());
//            AlarmManager mgr = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
//            mgr.set(AlarmManager.RTC, System.currentTimeMillis(), pendingIntent);
//            System.exit(2);
//            Process.killProcess(Process.myPid());
//        }
        //如果系统提供了默认的异常处理器，则交给系统去结束程序，否则就由自己结束自己
//        if (mDefaultCrashHandler != null) {
//            mDefaultCrashHandler.uncaughtException(thread, ex);
//        } else {
//            Process.killProcess(Process.myPid());
//        }
    }

    private Thread.UncaughtExceptionHandler restartHandler = new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
            Intent intent = new Intent(mContext, mClass);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
            Process.killProcess(Process.myPid());
        }
    };

    /**
     * 获取手机各项信息
     *
     * @param pw
     */
    private void dumpPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException {
        //得到包管理器
        PackageManager pm = mContext.getPackageManager();
        //得到包对象
        PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
        //写入APP版本号
        pw.print("App Version: ");
        pw.print(pi.versionName);
        pw.print("_");
        pw.println(pi.versionCode);
        //写入 Android 版本号
        pw.print("OS Version: ");
        pw.print(Build.VERSION.RELEASE);
        pw.print("_");
        pw.println(Build.VERSION.SDK_INT);
        //手机制造商
        pw.print("Vendor: ");
        pw.println(Build.MANUFACTURER);
        //手机型号
        pw.print("Model: ");
        pw.println(Build.MODEL);
        //CPU架构
        pw.print("CPU ABI: ");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            pw.println(Build.SUPPORTED_ABIS);
        } else {
            pw.println(Build.CPU_ABI);
        }
    }

    /**
     * 将错误信息上传至服务器
     */
    private void uploadExceptionToServer() {

    }

    public boolean checkIsAnr() {
        try {
            MessageQueue queue = Looper.getMainLooper().getQueue();
            @SuppressLint("DiscouragedPrivateApi") Field field = queue.getClass().getDeclaredField("mMessages");
            field.setAccessible(true);
            Message message = (Message) field.get(queue);
            // 注意！！！这里应该根据实际逻辑判断，比如在前台的话就相应的判断，比如超出5s，这里只是简单比较演示
            return message.getWhen() < SystemClock.uptimeMillis() - 5000;

// 可以dump这些消息
//        val processesInErrorStates = systemService.processesInErrorState
//        Log.i("hello", "processesInErrorStates ${processesInErrorStates}")
//        Log.i("hello", "checkIsANR")
//        Log.i("hello", "currentPid $currentPid")
//
//        processesInErrorStates?.let {
//            it.forEach { info ->
//                Log.i("hello", "pid is ${info.pid} ========${info.condition}")
//                if (info.pid == currentPid && info.condition == ActivityManager.ProcessErrorStateInfo
//                .NOT_RESPONDING) {
//                    Log.i("hello", "发生了anr")
//                    return true
//                }
//            }
//        }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public void handleAnr(@NonNull Context context, @NonNull String s) {
        LogUtil.crashHandlerLog("------------------程序ANR异常-----------------------------");
        LogUtil.crashHandlerLog("------------------程序自启动-----------------------------");
        try {
            Intent restart =
                new Intent(mContext.getPackageManager().getLaunchIntentForPackage(mContext.getPackageName()));
            restart.addFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            restart.setAction("restart");
            mContext.startActivity(restart);
            Process.killProcess(Process.myPid());
            System.exit(0);
        } catch (Throwable e) {
            LogUtil.crashHandlerLog("------------------handleAnr自启动失败-----------------------------");
            ProcessPhoenix.triggerRebirth(mContext);
        }
    }

    public void handleCrash(@NonNull Context context, int i, @NonNull String s) {
        LogUtil.crashHandlerLog("------------------程序native异常-----------------------------");
        LogUtil.crashHandlerLog("------------------程序自启动-----------------------------");
        try {
            Intent restart =
                new Intent(mContext.getPackageManager().getLaunchIntentForPackage(mContext.getPackageName()));
            restart.addFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            restart.setAction("restart");
            mContext.startActivity(restart);
            Process.killProcess(Process.myPid());
            System.exit(0);
        } catch (Throwable e) {
            LogUtil.crashHandlerLog("------------------handleCrash自启动失败-----------------------------");
            ProcessPhoenix.triggerRebirth(mContext);
        }
    }
}